#include "USART.h"

//#ifdef __GNUC__
///* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
//set to 'Yes') calls __io_putchar() */
//#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
//#else
//#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
//#endif /* __GNUC__ */
//#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
uint8_t uartRecvBuf[1024];
uint16_t usWritePos = 0;
uint16_t usReadPos = 0;
uint8_t ucWriteCicleNum = 0;
uint8_t ucReadCicleNum = 0;
uint16_t usWriteLen = 0;
uint16_t usReadLen = 0;
uint8_t ucFlag_UART_FIFOOverFlow = 0;

/*FROM LIUYANG*/
#pragma import(__use_no_semihosting)

//标准库需要的支持函数
struct __FILE
{
    int handle;
};

FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
_sys_exit(int x)
{
    x = x;
}

_ttywrch(int ch)    //可以消除这个错误
{
    ch=ch;
}

////重定义fputc函数
//int fputc(int ch, FILE *f)
//{
//    while ((USART2->SR & USART_FLAG_TXE) == RESET) {
//    }

//    USART2->DR = (uint8_t) ch;

//    return ch;
//}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
    while ((USART1->SR & USART_FLAG_TXE) == RESET) {
    }

    USART1->DR = (uint8_t) ch;

    return ch;
}

void SendData(int ch)
{
    while ((USART1->SR & USART_FLAG_TXE) == RESET) {
    }
    USART1->DR = (uint8_t) ch;
}

/**
  * @brief  Initializes the USART1.
  * @param  None
  * @retval None
  */
void USART1_Init(uint32_t Baudrate)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    //NVIC_InitTypeDef NVIC_InitStructure;

    /* config USART1 clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);
    /* USART1 GPIO config */

    /* Configure USART4 Tx (PC.10) as alternate function push-pull */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* Configure USART4 Rx (PC.11) as input floating */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* USART1 mode config */
    USART_InitStructure.USART_BaudRate = Baudrate;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No ;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
    USART_Init(USART1, &USART_InitStructure);

    //    USART_ITConfig(USART1, USART_IT_TC, ENABLE);
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

    USART_Cmd(USART1, ENABLE);
}

void USART2_Init(uint32_t Baudrate)
{
    /* USARTx configured as follow:
        - BaudRate =  Baudrate
        - Word Length = 8 Bits
        - One Stop Bit
        - No parity
        - Hardware flow control disabled (RTS and CTS signals)
        - Receive and transmit enabled
        */

    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    //NVIC_InitTypeDef NVIC_InitStructure;

    /* config USART1 clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
    /* USART1 GPIO config */
    /* Configure USART4 Tx (PC.10) as alternate function push-pull */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    /* Configure USART4 Rx (PC.11) as input floating */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* USART1 mode config */
    USART_InitStructure.USART_BaudRate = Baudrate;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No ;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
    USART_Init(USART2, &USART_InitStructure);

    //    USART_ITConfig(USART1, USART_IT_TC, ENABLE);
    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);

    USART_Cmd(USART2, ENABLE);
}

void uartDateLenUpdata(void)
{
    usWriteLen = ( uint16_t )ucWriteCicleNum * CICLELEN + usWritePos;
//    usReadLen = ( uint16_t )ucReadCicleNum * CICLELEN + usReadPos;
        usReadLen = usReadPos;
}

void uartDataLenUpdata_read( void )
{
//    usReadLen = ( uint16_t )ucReadCicleNum * CICLELEN + usReadPos;
    usReadLen = usReadPos;
}

void uartDataLenUpdata_write( void )
{
    usWriteLen = ( uint16_t )ucWriteCicleNum * CICLELEN + usWritePos;
}

void USART1_IRQHandler (void)
{
    if ( USART_GetITStatus( USART1, USART_IT_RXNE ) == SET )
    {
        uartDataLenUpdata_write();
        if ( ( usWriteLen - usReadLen ) > CICLELEN ) {
            ucFlag_UART_FIFOOverFlow = 1;
        } else {
            uartRecvBuf[usWritePos] = ( uint8_t )USART_ReceiveData( USART1 );

            usWritePos++;

            if ( usWritePos == CICLELEN ) {
                usWritePos = 0;
                ucWriteCicleNum++;
            }
        }

        USART_ClearITPendingBit( USART1,USART_IT_RXNE );
    }
}
